Fixed code which moved buffer around as new data comes in to work
authorMichael Fulbright <drmike@redhat.com>
Wed, 3 Nov 1999 17:17:32 +0000 (17:17 +0000)
committerMichael Fulbright <drmike@src.gnome.org>
Wed, 3 Nov 1999 17:17:32 +0000 (17:17 +0000)
1999-11-03  Michael Fulbright  <drmike@redhat.com>

* src/io-jpg.c image_load_increment(): Fixed code which moved
buffer around as new data comes in to work properly. JPEG progressive
loading should be working now except for grayscale JPEG's, which I

gdk-pixbuf/io-jpeg.c

index cfd15effcc565fcc298ae7204d1edc2ff98e8fa3..4f913d35e415726ad5ea405c64974e59099fb22f 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <config.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <setjmp.h>
 #include <jpeglib.h>
 #include "gdk-pixbuf.h"
 \f
 
 /* we are a "source manager" as far as libjpeg is concerned */
+#define JPEG_PROG_BUF_SIZE 4096
+
 typedef struct {
        struct jpeg_source_mgr pub;   /* public fields */
 
-       JOCTET * buffer;              /* start of buffer */
-       gboolean start_of_file;       /* have we gotten any data yet? */
+       JOCTET buffer[JPEG_PROG_BUF_SIZE];              /* start of buffer */
        long  skip_next;              /* number of bytes to skip next read */
 
 } my_source_mgr;
@@ -85,8 +88,6 @@ typedef struct {
        struct error_handler_data     jerr;
 } JpegProgContext;
 
-#define JPEG_PROG_BUF_SIZE 4096
-
 GdkPixbuf *image_load (FILE *f);
 gpointer image_begin_load (ModulePreparedNotifyFunc func, gpointer user_data);
 void image_stop_load (gpointer context);
@@ -227,7 +228,6 @@ init_source (j_decompress_ptr cinfo)
 {
        my_src_ptr src = (my_src_ptr) cinfo->src;
 
-       src->start_of_file = TRUE;
        src->skip_next = 0;
 }
 
@@ -278,7 +278,7 @@ image_begin_load (ModulePreparedNotifyFunc func, gpointer user_data)
        JpegProgContext *context;
        my_source_mgr   *src;
 
-       context = g_new (JpegProgContext, 1);
+       context = g_new0 (JpegProgContext, 1);
        context->notify_func = func;
        context->notify_user_data = user_data;
        context->pixbuf = NULL;
@@ -289,9 +289,8 @@ image_begin_load (ModulePreparedNotifyFunc func, gpointer user_data)
        /* create libjpeg structures */
        jpeg_create_decompress (&context->cinfo);
 
-       context->cinfo.src = (struct jpeg_source_mgr *) g_new (my_source_mgr, 1);
+       context->cinfo.src = (struct jpeg_source_mgr *) g_new0 (my_source_mgr, 1);
        src = (my_src_ptr) context->cinfo.src;
-       src->buffer = g_malloc (JPEG_PROG_BUF_SIZE);
 
        context->cinfo.err = jpeg_std_error (&context->jerr.pub);
 
@@ -316,6 +315,7 @@ void
 image_stop_load (gpointer data)
 {
        JpegProgContext *context = (JpegProgContext *) data;
+
        g_return_if_fail (context != NULL);
 
        if (context->pixbuf)
@@ -324,8 +324,6 @@ image_stop_load (gpointer data)
        if (context->cinfo.src) {
                my_src_ptr src = (my_src_ptr) context->cinfo.src;
                
-               if (src->buffer)
-                       g_free (src->buffer);
                g_free (src);
        }
 
@@ -352,12 +350,12 @@ image_load_increment (gpointer data, guchar *buf, guint size)
        struct jpeg_decompress_struct *cinfo;
        my_src_ptr  src;
        guint       num_left, num_copy;
-       guchar      *nextptr;
 
        g_return_val_if_fail (context != NULL, FALSE);
        g_return_val_if_fail (buf != NULL, FALSE);
 
        src = (my_src_ptr) context->cinfo.src;
+
        cinfo = &context->cinfo;
 
        /* skip over data if requested, handle unsigned int sizes cleanly */
@@ -374,23 +372,24 @@ image_load_increment (gpointer data, guchar *buf, guint size)
                num_left = size;
        }
 
+
        while (num_left > 0) {
                /* copy as much data into buffer as possible */
+
+               if(src->pub.bytes_in_buffer && 
+                  src->pub.next_input_byte != src->buffer)
+                       memmove(src->buffer, src->pub.next_input_byte,
+                               src->pub.bytes_in_buffer);
+
                num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer,
                                size);
 
                if (num_copy == 0) 
-                       g_assert ("Buffer overflow!\n");
+                       g_error ("Buffer overflow!");
 
-               nextptr = src->buffer + src->pub.bytes_in_buffer;
-               memcpy (nextptr, buf, num_copy);
-               
-               if (src->pub.next_input_byte == NULL ||
-                   src->pub.bytes_in_buffer == 0)
+               memcpy(src->buffer + src->pub.bytes_in_buffer, buf, num_copy);
                src->pub.next_input_byte = src->buffer;
-
                src->pub.bytes_in_buffer += num_copy;
-
                num_left -= num_copy;
 
                /* try to load jpeg header */
@@ -399,6 +398,7 @@ image_load_increment (gpointer data, guchar *buf, guint size)
 
                        rc = jpeg_read_header (cinfo, TRUE);
                        context->src_initialized = TRUE;
+
                        if (rc == JPEG_SUSPENDED)
                                continue;
 
@@ -418,7 +418,7 @@ image_load_increment (gpointer data, guchar *buf, guint size)
 
                        if (context->pixbuf == NULL) {
                                /* Failed to allocate memory */
-                               g_assert ("Couldn't allocate gdkpixbuf\n");
+                               g_error ("Couldn't allocate gdkpixbuf");
                        }
 
                        /* Use pixbuf buffer to store decompressed data */
@@ -430,7 +430,6 @@ image_load_increment (gpointer data, guchar *buf, guint size)
                                (* context->notify_func) (context->pixbuf,
                                                          context->notify_user_data);
 
-                       src->start_of_file = FALSE;
                } else if (!context->did_prescan) {
                        int rc;
 
@@ -461,9 +460,11 @@ image_load_increment (gpointer data, guchar *buf, guint size)
                                        rowptr += context->pixbuf->art_pixbuf->rowstride;;
                                }
 
+#ifdef IO_JPEG_DEBUG_GREY
                                for (p=lines[0],i=0; i< context->pixbuf->art_pixbuf->rowstride;i++, p++)
                                        *p = 0;
                                
+#endif
                                nlines = jpeg_read_scanlines (cinfo, lines,
                                                              cinfo->rec_outbuf_height);
                                if (nlines == 0)